#生成器--是特定的迭代器
'''
迭代器用于从数据集中取出元素；
生成器用于凭空生成元素，它不会一次性将所有元素全部生成，而是按
需一个一个地生成，所以从头到尾都只需占用一个元素的空间。

得到庞大的数据，但又想让它占用空间少，就可以用生成器。
节省空间内存

'''
#生成器函数：yield
'''
使用yield语句返回一个结果，在每个结果中间，挂起函数的状态，
以便下次从它离开的地方继续执行。
第一次调用完后状态挂起，下次执行时，从挂起的位置继续执行。

'''
def funa():
    yield 1
    return '出现异常'   #返回一个值是StopIteration的说明，而不是程序返回值。

sixstar = funa()
print(next(sixstar))    #1
#print(next(sixstar))    #StopIteration: 出现异常
print('==========================================================================')
print('\n')


def funa1():
    print('-----haha------')
    yield 'a'
    yield 'b'
#取值方式一：
fn = funa1()
print(next(fn))

#取值方式二：
for i in funa1():
    print(i)
print('==========================================================================')
print('\n')


#yield的应用场景
'''
处理文件，用户指定要查找的文件和内容，将文件中包含要查找的内容
的每一行都输出到屏幕。
'''
def funa2(fname,word):
    with open(fname,encoding='utf-8') as file:
        for i in file:  #i代表行
            if word in i: #word代表要查找的字符串内容
                yield i

#查找文件中的内容hehe
t = funa2(r'C:\Users\sea_0\Desktop\silicon\doctest0411.txt','hehe')
print(next(t))
print(next(t))
print('==========================================================================')
print('\n')



#创建生成器
'''
只要把列表生成式中的[]改成()即可
'''
#例
list1 = [i*2 for i in range(3)]  #列表推导式
print(list1)                     #[0, 2, 4]

#创建生成器表达式
list2 = (i*2 for i in range(3))  #生成器表达式
print(list2)                     #<generator object <genexpr> at 0x0000017E60CFE190>
print(next(list2))               #0
print(next(list2))               #2
print(next(list2))               #4
#生成器按需要生成数据，只占一个元素内存空间，缩短计算时间，提高效率



#yield 与 return的区别
'''
相同点：都是返回函数执行的结果
不同点：return在返回结果后结束函数的运行
yield让函数变成一个生成器

yield生成器相比return一次返回所有的结果的优势：
1.反应更迅速
2.更节省空间
3.使用更加灵活

'''





















